package com.cqch.service.impl;

import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.cqch.dao.RegistryRepository;
import com.cqch.dao.UserRepository;
import com.cqch.pojo.entity.EmailCode;
import com.cqch.pojo.entity.User;
import com.cqch.pojo.repVo.BaseResp;
import com.cqch.pojo.repVo.UserRepVo;
import com.cqch.pojo.reqVo.UserReqVo;
import com.cqch.service.UserService;
import com.cqch.utils.JwtUtils;
import com.cqch.utils.Sample;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Random;

/**
 * @Author CQCH
 * @Description
 * @Date 2022/3/29
 */
@Service
public class UserServiceImpl implements UserService {


    @Autowired  //自动注入dao层
    UserRepository userRepository;

    @Autowired  //自动注入密钥
    JwtUtils jwtUtils;

    @Autowired  //自动注入 redis存储
    RedisTemplate redisTemplate;

    @Autowired  //自动注入rabbitmq
    RabbitTemplate rabbitTemplate;

    @Autowired
    RegistryRepository registryRepository;

    @Autowired
    Sample sample;


    //注册
    @Override
    public BaseResp registry(@RequestBody UserReqVo userReqVo) {

        //验证码注册
        String mail = userReqVo.getMail();

        //检查用户名
        User liveUser = userRepository.findByLoginName(userReqVo.getLoginName());
        if (liveUser!=null){
            return new BaseResp(0,"登录名被占用！",null,null);
        }
        //验证码的比对
        Boolean aBoolean = redisTemplate.hasKey(mail);
        if (!aBoolean){
            return new BaseResp(0,"验证码已过期!",null,null);
        }
        Object o = redisTemplate.opsForValue().get(mail);
        if (!userReqVo.getCode().equals(o.toString())){
            return new BaseResp(0,"验证码输入错误!",null,null);
        }
        //存储到数据库中
        User UserSave = new User();
        BeanUtils.copyProperties(userReqVo,UserSave);
        userRepository.save(UserSave);

        return new BaseResp(1,"注册成功！",null,null);

    }

    //用户名登录
    @Override
    public BaseResp login(UserReqVo userReqVo) {

        if (userReqVo.getLoginName()==null){
            return new BaseResp(0,"用户名不能为空！",null,null);
        }
        if (userReqVo.getPassword()==null){
            return new BaseResp(0,"密码不能为空！",null,null);
        }
        //使用用户名查询出对象
        User byLoginName = userRepository.findByLoginName(userReqVo.getLoginName());
        if (byLoginName==null){
            return new BaseResp(0,"没有该用户！",null,null);
        }
        //比对密码
        if (!byLoginName.getPassword().equals(userReqVo.getPassword())){
            return new BaseResp(0,"密码输入错误！",null,null);
        }
        //登录成功 我们需要生成token串返回到前端
        Map map = new HashMap<>();
        map.put("name",byLoginName.getLoginName());
        map.put("mail","123");
        map.put("phone","213");
        map.put("id",byLoginName.getId());
        String token = jwtUtils.signToken(map);

        return new BaseResp(1,"登录成功!",token,null);

    }

    @Override
    public BaseResp findUserByToken(HttpServletRequest request) {
        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)){
            return new BaseResp(0,"token为null",null,null);
        }
        //使用jwt解析Token

        Integer verfiy = jwtUtils.verfiy(token);
        if (verfiy==0){
            return new BaseResp(0,"token验证失败！",null,null);
        }
        //从数据库查询出用户的数据
        Optional<User> byId = userRepository.findById(verfiy);
        if (!byId.isPresent()){
            return new BaseResp(0,"没有该用户！",null,null);
        }
        UserRepVo userRepVo = new UserRepVo();
        BeanUtils.copyProperties(byId.get(),userRepVo);
        return new BaseResp(1,"验证成功！",userRepVo,null);
    }


    /*@Override
    public BaseResp validataEmail(String email) {
        return null;
    }*/

    //判断登录名是否被占用
    @Override
    public BaseResp validataloginName(UserReqVo userReqVo) {

        if(userReqVo.getLoginName()==null){
            return new BaseResp().Error();
        }
        User byLoginName = userRepository.findByLoginName(userReqVo.getLoginName());
        if(byLoginName!=null){
            return new BaseResp(0,"登录名被占用",null,null);
        }
        return new BaseResp(1,"登录名可用",null,null);
    }

    @Override  //发送邮件验证码
    public BaseResp getCode(String mail) {
        if (mail==null){
            return new BaseResp().Error();
        }
        User byEmail = userRepository.findByMail(mail);
        if (byEmail!=null){
            return new BaseResp(0,"邮箱已被占用！",null,null);
        }
        //准备将 收件人以及 验证码通过异步通信，发送给rabbitmq，进行处理
        StringBuffer stringBuffer = new StringBuffer();
        for (int i=0;i<6;i++){
            stringBuffer.append(new Random().nextInt(10));
        }
        String code =stringBuffer.toString();

        //1.声明map
        Map map=new HashMap();
        map.put("email",mail);
        map.put("code",code);
        //通过rabbitmq进行异步通信
        rabbitTemplate.convertAndSend("","user-mail",map);
        return new BaseResp(1,"发送成功",null,null);
    }

    @Override  //发送手机验证码
    public BaseResp phone(String phone) {
        //1.判断验证码
        if (phone == null) {
            return new BaseResp(0, "手机号不能为空！", null, null);

        }
        EmailCode byPhoneAndStatus1 = registryRepository.findByPhoneAndStatus(phone, 1);
        if (byPhoneAndStatus1 != null) {
            return new BaseResp(0, "该手机号已被注册", null, null);
        }

        StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < 6; i++) {
            Random random = new Random();
            int i1 = random.nextInt(10);
            buffer.append(i1);
        }
        try {
            Client client = sample.createClient("LTAI5tNnpEH9daATZxPJb8TM", "xVfw3mQn4TZ7HAnXrZSFo5MT4JopfY");
            SendSmsRequest sendSmsRequest = new SendSmsRequest()
                    .setSignName("阿里云短信测试")
                    .setTemplateCode("SMS_154950909")
                    .setPhoneNumbers(phone)
                    .setTemplateParam("{\"code\":" + buffer + "}");
            SendSmsResponse resp = client.sendSms(sendSmsRequest);

            // com.aliyun.teaconsole.Client.log(com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(resp)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        EmailCode byPhoneAndStatus = registryRepository.findByPhoneAndStatus(phone, 0);
        if (byPhoneAndStatus != null) {
            byPhoneAndStatus.setCode(buffer.toString());
            registryRepository.saveAndFlush(byPhoneAndStatus);
        } else {
            EmailCode emailCode = new EmailCode();
            emailCode.setCode(buffer.toString());
            emailCode.setPhone(phone);
            emailCode.setStatus(0);
            registryRepository.saveAndFlush(emailCode);

        }
        return new BaseResp(1, "发送成功", null, null);
    }

    @Override   //手机号注册
    public BaseResp registryPhone(UserReqVo userReqVo) {
        System.out.println(userReqVo);
        //1.判断手机号
        String phone = userReqVo.getPhone();
        if (phone == null) {
            return new BaseResp(0, "手机号不能为空！", null, null);
        }
        EmailCode byPhoneAndStatus = registryRepository.findByPhoneAndStatus(phone, 1);

        //判断手机号是否已存在
        if (byPhoneAndStatus != null) {
            return new BaseResp(0, "手机号已被注册！", null, null);
        }
        EmailCode byPhoneAndStatus1 = registryRepository.findByPhoneAndStatus(phone, 0);
        System.out.println(byPhoneAndStatus1);
        if (byPhoneAndStatus1 == null) {
            return new BaseResp(0, "请先发送验证码！", null, null);
        }
        if (!byPhoneAndStatus1.getCode().equals(userReqVo.getCode())) {
            return new BaseResp(0, "验证码输入错误！", null, null);

        }
        //2.判断用户名是否存在
        User byUserName = userRepository.findByLoginName(userReqVo.getLoginName());
        if (byUserName != null) {
            return new BaseResp(0, "用户名已被注册！", null, null);
        }
        //3.存储进入数据库
        //将前端请求对象中的数据复制到jpa对象中
        User user = new User();
        //保证属性名保持一致，才能复制
        BeanUtils.copyProperties(userReqVo, user);
        userRepository.save(user);
        //更改当前 emali_code表中的status 改为1 代表已经使用该邮箱
        byPhoneAndStatus1.setCode("1");
        registryRepository.save(byPhoneAndStatus1);
        return new BaseResp(1, "注册成功！", null, null);

    }

    @Override//手机号登录
    public BaseResp loginPhone(UserReqVo userReqVo) {
        User byLoginName = userRepository.findByPhone(userReqVo.getPhone());
        if (byLoginName == null) {
            return new BaseResp(0, "此手机号未注册", null, null);

        }
        if (!byLoginName.getPassword().equals(userReqVo.getPassword())) {
            return new BaseResp(0, "密码错误！", null, null);
        }
        //生成用户的ticket票据，token串
        Map map = new HashMap();
        map.put("phone", byLoginName.getPhone());
        map.put("mail","123");
        map.put("name", "123");
        map.put("id", byLoginName.getId());
        String token = jwtUtils.signToken(map);

        return new BaseResp(1, "登录成功！", token, null);
    }

    @Override  //邮箱登录
    public BaseResp loginEmail(UserReqVo userReqVo) {
        User byLoginName = userRepository.findByMail(userReqVo.getMail());
        if (byLoginName == null) {
            return new BaseResp(0, "此邮箱未绑定", null, null);

        }
        if (!byLoginName.getPassword().equals(userReqVo.getPassword())) {
            return new BaseResp(0, "密码错误！", null, null);
        }
        //生成用户的ticket票据，token串
        Map map = new HashMap();
        map.put("mail",byLoginName.getMail());
        map.put("phone","123");
        map.put("name","123");
        map.put("id", byLoginName.getId());
        String token = jwtUtils.signToken(map);

        return new BaseResp(1, "登录成功！", token, null);
    }

    @Override
    public BaseResp validataPhone(UserReqVo userReqVo) {

        if(userReqVo.getPhone()==null){
            return new BaseResp().Error();
        }
        User byPhone = userRepository.findByPhone(userReqVo.getPhone());
        if(byPhone!=null){
            return new BaseResp(0,"手机号已被注册",null,null);
        }
        return new BaseResp(1,"手机号可注册",null,null);
    }

}
